package com.example.joemi.carpool;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Looper;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.location.Poi;
import com.baidu.mapapi.SDKInitializer;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.map.PolygonOptions;
import com.baidu.mapapi.map.PolylineOptions;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.overlayutil.TransitRouteOverlay;
import com.baidu.mapapi.search.core.PoiInfo;
import com.baidu.mapapi.search.route.TransitRouteLine;

import org.json.JSONArray;
import org.json.JSONObject;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends Activity {

    MapView mapView = null;
    BaiduMap baiduMap = null;
    LocationClient locationClient;
    MyLocationData locationData = null;
    LatLng sourceSpotLatLng;
    BDLocationListener myListener = new MyLocationListener();
    volatile boolean isFirstLocation = true;

    List<Poi> locationPoiList;

    TextView myLocation;
    TextView myTerminus;
    TextView myCarpoolPrice;
    TextView myNoCarpoolPrice;
    Button callCarButton;
    Button cancelButton;

    public static PoiInfo terminusPoiInfo = null;
    public static PoiInfo sourcePoiInfo = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SDKInitializer.initialize(getApplicationContext());
        setContentView(R.layout.activity_main);

        mapView = (MapView)findViewById(R.id.bmapView);
        baiduMap = mapView.getMap();
        baiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
        baiduMap.setMyLocationEnabled(true);
        baiduMap.clear();
        baiduMap.setMapStatus(MapStatusUpdateFactory.newMapStatus(new MapStatus.Builder().zoom(15).build()));

        myLocation = (TextView)findViewById(R.id.locationTextView);
        myLocation.setClickable(true);
        myLocation.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, SourceActivity.class);
                startActivityForResult(intent, 200);
            }
        });
        myTerminus = (TextView)findViewById(R.id.terminusTextView);
        myTerminus.setClickable(true);
        myTerminus.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, TerminusActivity.class);
                startActivityForResult(intent, 100);
            }
        });

        myCarpoolPrice = (TextView)findViewById(R.id.carpool_text_view);
        myCarpoolPrice.setClickable(true);
        myCarpoolPrice.setVisibility(View.GONE);
        myNoCarpoolPrice = (TextView)findViewById(R.id.no_carpool_text_view);
        myNoCarpoolPrice.setClickable(true);
        myNoCarpoolPrice.setVisibility(View.GONE);
        callCarButton = (Button)findViewById(R.id.call_car_button);
        callCarButton.setVisibility(View.GONE);

        locationClient = new LocationClient(getApplication());
        initLocation();
        locationClient.registerLocationListener(myListener);
        locationClient.start();

        callCarButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showCarLine();
                afterShowCarLine();
            }
        });

        cancelButton = (Button)findViewById(R.id.cancel_button);
        cancelButton.setVisibility(View.GONE);
        cancelButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                returnToBegin();
            }
        });
    }

    /**
     * 定位的初始化
     */
    private void initLocation(){
        LocationClientOption option = new LocationClientOption();
        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy
        );//可选，默认高精度，设置定位模式，高精度，低功耗，仅设备
        option.setCoorType("bd09ll");//可选，默认gcj02，设置返回的定位结果坐标系
        int span=0;
        option.setScanSpan(span);//可选，默认0，即仅定位一次，设置发起定位请求的间隔需要大于等于1000ms才是有效的
        option.setIsNeedAddress(true);//可选，设置是否需要地址信息，默认不需要
        option.setOpenGps(true);//可选，默认false,设置是否使用gps
        option.setLocationNotify(true);//可选，默认false，设置是否当gps有效时按照1S1次频率输出GPS结果
        option.setIsNeedLocationDescribe(true);//可选，默认false，设置是否需要位置语义化结果，可以在BDLocation.getLocationDescribe里得到，结果类似于“在北京天安门附近”
        option.setIsNeedLocationPoiList(true);//可选，默认false，设置是否需要POI结果，可以在BDLocation.getPoiList里得到
        option.setIgnoreKillProcess(false);//可选，默认false，定位SDK内部是一个SERVICE，并放到了独立进程，设置是否在stop的时候杀死这个进程，默认杀死
        option.SetIgnoreCacheException(false);//可选，默认false，设置是否收集CRASH信息，默认收集
        option.setEnableSimulateGps(false);//可选，默认false，设置是否需要过滤gps仿真结果，默认需要
        locationClient.setLocOption(option);
    }

    /**
     * 以下函数没有做过更改
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        //在activity执行onDestroy时执行mMapView.onDestroy()，实现地图生命周期管理
        mapView.onDestroy();
    }
    @Override
    protected void onResume() {
        super.onResume();
        //在activity执行onResume时执行mMapView. onResume ()，实现地图生命周期管理
        mapView.onResume();
    }
    @Override
    protected void onPause() {
        super.onPause();
        //在activity执行onPause时执行mMapView. onPause ()，实现地图生命周期管理
        mapView.onPause();
    }
    @Override
    protected void onStart() {
        baiduMap.setMyLocationEnabled(true);
        if(!locationClient.isStarted()) {
            locationClient.start();
        }
        super.onStart();
    }
    @Override
    protected void onStop() {
        baiduMap.setMyLocationEnabled(false);
        locationClient.stop();
        super.onStop();
    }

    /**
     * 将推荐的上车地点描绘在地图上
     */
    void drawSuggestionSpot() {
        if(sourceSpotLatLng == null) return;
        Toast.makeText(this, "正在加载推荐上车地点", Toast.LENGTH_SHORT).show();
        new Thread() {
            public void run() {
                try {
                    ByteArrayOutputStream outStream = new ByteArrayOutputStream();
                    byte[] data = new byte[1024];
                    Log.i("LatLng", sourceSpotLatLng.latitude+", "+sourceSpotLatLng.longitude);
                    URL url = new URL("http://166.111.71.171:8000/recommend_boards?type=4&latitude=" + sourceSpotLatLng.latitude + "&longitude=" + sourceSpotLatLng.longitude);
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    InputStream inStream = conn.getInputStream();
                    int len = 0;
                    while ((len = inStream.read(data)) != -1) {
                        outStream.write(data, 0, len);
                    }
                    inStream.close();
                    String jsonString = new String(outStream.toByteArray());
                    Log.i("jsonString", jsonString);
                    JSONObject json = new JSONObject(jsonString).getJSONObject("data");
                    JSONArray jsonArray = json.getJSONArray("rmd_pois");
                    BitmapDescriptor bitmap = BitmapDescriptorFactory
                            .fromResource(R.drawable.location_marker_small);
                    for(int i = 0; i < jsonArray.length(); i++) {
                        JSONObject start_spot = (JSONObject)jsonArray.get(i);
                        double lat = (double)start_spot.get("latitude");
                        double lng = (double)start_spot.get("longitude");
                        int rank = (int)start_spot.get("rank");
                        LatLng point = new LatLng(lat, lng);
                        OverlayOptions options = new MarkerOptions().position(point).icon(bitmap).title(rank+"");
                        baiduMap.addOverlay(options);
                    }
                } catch (Exception e) {
                    Log.i("Exception:", e.toString());
                }
            }
        }.start();
    }

    /**
     * 在地图上显示出行车路线，前提：已知出发地和目的地
     */
    void showCarLine() {
        if(sourceSpotLatLng == null || MainActivity.terminusPoiInfo == null) {
            Toast.makeText(MainActivity.this, "未选定上车位置或目的地", Toast.LENGTH_LONG).show();
            return;
        }
        new Thread() {
            public void run() {
                try {
                    ByteArrayOutputStream outStream = new ByteArrayOutputStream();
                    byte[] data = new byte[1024];
                    URL url = new URL("http://166.111.71.174:8000/carpooling/carpooling.fcgi?query="
                            +sourceSpotLatLng.latitude+","
                            +sourceSpotLatLng.longitude+","
                            +MainActivity.terminusPoiInfo.location.latitude+","
                            +MainActivity.terminusPoiInfo.location.longitude+",type=search_route");
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    InputStream inStream = conn.getInputStream();
                    int len = 0;
                    while ((len = inStream.read(data)) != -1) {
                        outStream.write(data, 0, len);
                    }
                    inStream.close();
                    String jsonString = new String(outStream.toByteArray());
                    JSONArray json = new JSONArray(jsonString);
                    JSONArray jsonArray = ((JSONObject)json.get(0)).getJSONArray("route");
                    List<LatLng> points = new ArrayList<LatLng>();
                    for(int i = 0; i < jsonArray.length(); i++) {
                        JSONObject p = (JSONObject)jsonArray.get(i);
                        points.add(new LatLng((double)p.get("lat"), (double)p.get("lng")));
                    }
                    OverlayOptions ooPolyline = new PolylineOptions().width(5).points(points);
                    baiduMap.addOverlay(ooPolyline);
                } catch(Exception e) {
                    Log.i("ShowCarLine Exception", e.toString());
                    Looper.prepare();
                    Toast.makeText(MainActivity.this, e.toString(), Toast.LENGTH_LONG).show();
                    Looper.loop();
                }
            }
        }.start();
    }

    private void showCars() {
        new Thread() {
            public void run() {
                try {
                    ByteArrayOutputStream outStream = new ByteArrayOutputStream();
                    byte[] data = new byte[1024];
                    URL url = new URL("http://166.111.71.174:8000/carpooling/carpooling.fcgi?query=39.996895,116.321731,type=search_cars");
                    HttpURLConnection conn = (HttpURLConnection)url.openConnection();
                    InputStream inStream = conn.getInputStream();
                    int len = 0;
                    while ((len = inStream.read(data)) != -1) {
                        outStream.write(data, 0, len);
                    }
                    inStream.close();
                    String jsonString = new String(outStream.toByteArray());
                    JSONArray json = new JSONArray(jsonString);
                    JSONArray jsonArray = ((JSONObject)json.get(0)).getJSONArray("cars");
                    BitmapDescriptor bitmap = BitmapDescriptorFactory
                            .fromResource(R.drawable.location_marker_small);
                    for(int i = 0; i < jsonArray.length(); i++) {
                        JSONObject spot = (JSONObject)jsonArray.get(i);
                        String id = (String)spot.get("id");
                        double lat = (double)spot.get("lat");
                        double lng = (double)spot.get("lng");
                        LatLng point = new LatLng(lat, lng);
                        OverlayOptions options = new MarkerOptions().position(point).icon(bitmap).title(id);
                        baiduMap.addOverlay(options);
                    }
                } catch(Exception e) {
                    Log.i("showCars Exception", e.toString());
                }
            }
        }.start();
    }

    /**
     * MainActivity会调用子活动后，调用的函数
     */
    protected void onActivityResult(int requestCode,int resultCode,Intent data) {
        /**
         * requestCode ： 100 from TerminusActivity | 200 from SourceActivity
         * resultCode  :  20 to MainActivity | 40 to MainActivity
         */
        if(requestCode == 100 && resultCode == 20) {
            PoiInfo tmpi = MainActivity.terminusPoiInfo;
            if(tmpi != null) { myTerminus.setText(tmpi.name); }
        }
        if(requestCode == 200 && resultCode == 40) {
            PoiInfo scpi = MainActivity.sourcePoiInfo;
            if(scpi != null) {
                myLocation.setText(scpi.name);
                sourceSpotLatLng = scpi.location;
                baiduMap.clear();
                MyLocationData ld = new MyLocationData.Builder()
                        .latitude(sourceSpotLatLng.latitude)
                        .longitude(sourceSpotLatLng.longitude).build();
                baiduMap.setMyLocationData(ld);
                MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(sourceSpotLatLng);
                baiduMap.animateMapStatus(u);
                baiduMap.setMapStatus(MapStatusUpdateFactory.newMapStatus(new MapStatus.Builder().zoom(18).build()));
                drawSuggestionSpot();
                showCars();
            }
        }
        if(MainActivity.terminusPoiInfo != null) {
            startNextStep();
        }
    }

    /**
     * 这一部分是选好了出发地和目的地时展开的
     */
    private void startNextStep() {
        myCarpoolPrice.setVisibility(View.VISIBLE);
        myNoCarpoolPrice.setVisibility(View.VISIBLE);
        callCarButton.setVisibility(View.VISIBLE);
    }

    private void afterShowCarLine() {
        myTerminus.setVisibility(View.GONE);
        myLocation.setVisibility(View.GONE);
        myCarpoolPrice.setVisibility(View.GONE);
        myNoCarpoolPrice.setVisibility(View.GONE);
        callCarButton.setVisibility(View.GONE);
        cancelButton.setVisibility(View.VISIBLE);
    }

    private void returnToBegin() {
        myTerminus.setVisibility(View.VISIBLE);
        myLocation.setVisibility(View.VISIBLE);
        myCarpoolPrice.setVisibility(View.VISIBLE);
        myNoCarpoolPrice.setVisibility(View.VISIBLE);
        callCarButton.setVisibility(View.VISIBLE);
        cancelButton.setVisibility(View.GONE);
        baiduMap.clear();
        drawSuggestionSpot();
        showCars();
    }

    /**
     * 定位监听
     */
    class MyLocationListener implements BDLocationListener {

        @Override
        public void onReceiveLocation(BDLocation location) {
            if(!isFirstLocation) return;
            locationPoiList = (List<Poi>)location.getPoiList(); //POI数据
            locationData = new MyLocationData.Builder()
                    .accuracy(location.getRadius())
                    .latitude(location.getLatitude())
                    .longitude(location.getLongitude()).build();
            LatLng ll = new LatLng(location.getLatitude(), location.getLongitude());
            sourceSpotLatLng = new LatLng(location.getLatitude(), location.getLongitude());
            MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(ll);
            baiduMap.animateMapStatus(u);
            baiduMap.setMyLocationData(locationData);
            baiduMap.setMapStatus(MapStatusUpdateFactory.newMapStatus(new MapStatus.Builder().zoom(18).build()));
            drawSuggestionSpot();
            showCars();
            if(locationPoiList !=  null) {
                myLocation.setText(locationPoiList.get(0).getName());
                locationClient.stop();
                isFirstLocation = false;
            } else {
                Toast.makeText(MainActivity.this, "无法获取地图信息，请检查一下网络设置", Toast.LENGTH_LONG).show();
                myLocation.setText("你从哪出发");
            }
        }
    }
}
